/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package phd.dupenois.es.nplusn;

/**
 *
 * @param <T>
 * @author mpd209
 */
public class Objective<T extends Number> {
    private String name;
    private boolean minimise;
    public Objective(String name, boolean minimise){
        this.name = name;
        this.minimise = minimise;
    }
    public boolean isValueValid(Number value){
        try {
            cast(value);
            return true;
        } catch (ClassCastException e) {
            return false;
        }
    }
//    public Class getObjectiveClass(){
//        return this.getClass().;
//    }

    public Domination compareValues(Number myValue, Number otherValue){
        T myVal = cast(myValue);
        T otherVal = cast(otherValue);
        Domination domination = Domination.MUTUALLY_NON_DOMINATING;
        if(myVal instanceof Integer){
            if((isMinimise()&&myVal.intValue() < otherVal.intValue())||
            ((!isMinimise())&&myVal.intValue() > otherVal.intValue())){
                domination = Domination.DOMINATES;
            }else if((isMinimise()&&myVal.intValue() > otherVal.intValue())||
            ((!isMinimise())&&myVal.intValue() < otherVal.intValue())){
                domination = Domination.DOMINATED;
            }
        }else if(myVal instanceof Double){
            if((isMinimise()&&myVal.doubleValue() < otherVal.doubleValue())||
            ((!isMinimise())&&myVal.doubleValue() > otherVal.doubleValue())){
                domination = Domination.DOMINATES;
            }else if((isMinimise()&&myVal.doubleValue() > otherVal.doubleValue())||
            ((!isMinimise())&&myVal.doubleValue() < otherVal.doubleValue())){
                domination = Domination.DOMINATED;
            }

        }else if(myVal instanceof Float){
            if((isMinimise()&&myVal.floatValue() < otherVal.floatValue())||
            ((!isMinimise())&&myVal.floatValue() > otherVal.floatValue())){
                domination = Domination.DOMINATES;
            }else if((isMinimise()&&myVal.floatValue() > otherVal.floatValue())||
            ((!isMinimise())&&myVal.floatValue() < otherVal.floatValue())){
                domination = Domination.DOMINATED;
            }
        }else if(myVal instanceof Long){
            if((isMinimise()&&myVal.longValue() < otherVal.longValue())||
            ((!isMinimise())&&myVal.longValue() > otherVal.longValue())){
                domination = Domination.DOMINATES;
            }else if((isMinimise()&&myVal.longValue() > otherVal.longValue())||
            ((!isMinimise())&&myVal.longValue() < otherVal.longValue())){
                domination = Domination.DOMINATED;
            }
        }else if(myVal instanceof Short){
            if((isMinimise()&&myVal.shortValue() < otherVal.shortValue())||
            ((!isMinimise())&&myVal.shortValue() > otherVal.shortValue())){
                domination = Domination.DOMINATES;
            }else if((isMinimise()&&myVal.shortValue() > otherVal.shortValue())||
            ((!isMinimise())&&myVal.shortValue() < otherVal.shortValue())){
                domination = Domination.DOMINATED;
            }
        }else if(myVal instanceof Byte){
            if((isMinimise()&&myVal.byteValue() < otherVal.byteValue())||
            ((!isMinimise())&&myVal.byteValue() > otherVal.byteValue())){
                domination = Domination.DOMINATES;
            }else if((isMinimise()&&myVal.byteValue() > otherVal.byteValue())||
            ((!isMinimise())&&myVal.byteValue() < otherVal.byteValue())){
                domination = Domination.DOMINATED;
            }

        }
        return domination;
    }


    public T cast(Number value){
        return (T) value;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the minimise
     */
    public boolean isMinimise() {
        return minimise;
    }

    @Override
    public boolean equals(Object other){
        if(this == other) return true;
        if(!(other.getClass().equals(this.getClass())))return false;
        Objective<T> oObjective;
        try {
            oObjective = (Objective<T>) other;
        } catch (ClassCastException e) {
            return false;
        }
        if(!this.name.equals(oObjective.getName()))return false;
        if(this.minimise!=oObjective.isMinimise()) return false;
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 13 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 13 * hash + (this.minimise ? 1 : 0);
        return hash;
    }

}
